/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlet.edt;

import bdd.DBLink;
import beans.Creneau;
import beans.Ec;
import beans.Enseignant;
import beans.Jours;
import beans.Role;
import beans.Salle;
import beans.Type;
import beans.Typeposte;
import beans.Ue;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author maboisba
 */
public class VerificationServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    DBLink dbLink = new DBLink();
    dbLink.connexion();
    PrintWriter out = resp.getWriter();
    out.println("Test");
    /*
    List<Creneau> liste = dbLink.listeCreneaux();
    for (Creneau creneau : liste) {
    out.println(creneau.getHorairedebut() + " - " + creneau.getHorairefin());
    }*/

    List<Jours> liste = dbLink.listeJours();
    for (Jours jour : liste) {
      String date = "" + jour.getIddate();
      out.println(jour.getIddate());
      System.out.println("Date = " + date);
    }

    verifierContraintes(req);

  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req, resp);
  }

  private void verifierContraintes(HttpServletRequest req) {
    try {
      String url = req.getRealPath("erreurs.log");
      File file = new File(url);
      file.delete();
      file.createNewFile();
      OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(url), "ISO-8859-1");
      BufferedWriter bw = new BufferedWriter(out);

      String message = "";

      //***************************** Pour les tests ***************************
      Ec ec = new Ec(1, new Ue(), "Marketing", 2.5);
      Type type = new Type(3, "cours");
      DBLink dbLink = new DBLink();
      dbLink.connexion();
      List<Jours> liste = dbLink.listeJours();
      Jours jour = liste.get(0);
      Salle salle = new Salle(1, (short) 30, "100a-A");
      Enseignant enseignant = new Enseignant(1, new Typeposte(), new Role(), "Dupont", "Albert",
              "4 rue de la rose 75000 Paris", 0601015214, new Date(), "", "");
      //************************************************************************

      message = verifierEc(ec, type);
      if (!message.equals("")) {
        ecrireMessageErreur(bw, message);
      }

      message = verifierJournee(jour);
      if (!message.equals("")) {
        ecrireMessageErreur(bw, message);
      }

      message = verifierSemaine(jour);
      if (!message.equals("")) {
        ecrireMessageErreur(bw, message);
      }

      message = verifierSalle(jour, salle);
      if (!message.equals("")) {
        ecrireMessageErreur(bw, message);
      }

      message = verifierIntervenant(jour, enseignant);
      if (!message.equals("")) {
        ecrireMessageErreur(bw, message);
      }

      bw.flush();
      out.flush();
      bw.close();
      out.close();
    }
    catch (IOException ioe) {
      ioe.printStackTrace();
    }

  }

  private String verifierEc(Ec ec, Type type) {
    String message = "";
    int nbHeuresMaquette = 8;
    /** @TODO : Appel à la requête du groupe BDD pour le contrôle des EC */
    int nbHeures = 8;
    /** @TODO : Appel à la requête du groupe BDD pour le contrôle des EC */
    int diff = nbHeuresMaquette - nbHeures;

    if (diff < 0) {
      message = Math.abs(diff) + " heures ont été affectées en trop pour l'EC '" + ec.getLibelle() + "'.";
    }
    else if (diff > 0) {
      message = "Il reste " + diff + " heures à affecter pour l'EC '" + ec.getLibelle() + "'.";
    }

    return message;
  }

  private String verifierJournee(Jours jour) {
    String message = "";
    List<Creneau> creneaux = new ArrayList<Creneau>();
    /** @TODO : Appel à la requête du groupe BDD pour le contrôle des créneaux par journée */
    //***************************** Pour les tests *****************************
    Creneau cr1 = new Creneau();
    cr1.setHorairedebut(700);
    cr1.setHorairefin(1230);

    Creneau cr2 = new Creneau();
    cr2.setHorairedebut(1300);
    cr2.setHorairefin(1600);

    creneaux.add(cr1);
    creneaux.add(cr2);
    //***************************** Pour les tests *****************************
    float nombreHeures = 0;
    for (Creneau creneau : creneaux) {
      int heureDebutInt = (int) (creneau.getHorairedebut() / 100);
      System.out.println("heureDebutInt = " + heureDebutInt);

      int heureFinInt = (int) (creneau.getHorairefin() / 100);
      System.out.println("heureFinInt = " + heureFinInt);

      nombreHeures += heureFinInt - heureDebutInt;
      System.out.println("nombreHeures = " + nombreHeures);

      int minuteDebutInt = (int) (creneau.getHorairedebut() % 100);
      System.out.println("minuteDebutInt = " + minuteDebutInt);

      int minuteFinInt = (int) (creneau.getHorairefin() % 100);
      System.out.println("minuteFinInt = " + minuteFinInt);

      nombreHeures += ((float) minuteFinInt - (float) minuteDebutInt) / 60;
      System.out.println("nombreHeures = " + nombreHeures);
      System.out.println("========================================");
    }
    if (nombreHeures > 8) {
      int heures = (int) (nombreHeures - 8);
      System.out.println("(nombreHeures - 8 ) - heures = " + (int) (((nombreHeures - 8) - heures) * 60));
      int minutes = (int) (((nombreHeures - 8) - heures) * 60);
      String date = "" + jour.getIddate();
      System.out.println("date : " + date);
      message = "La journée du " + date.substring(0, 10) + " compte " + heures + "h" + minutes;
      if (minutes == 0) {
        message += "0";
      }
      message += " de trop. Une journée ne doit pas excéder 8 heures.\n";
    }

    return message;
  }

  private String verifierSemaine(Jours jour) {
    String message = "";
    /*
    Date d = (Date) jour.getIddate();
    //Calendar calendar = new GregorianCalendar();
    System.out.println("test semaine2");
  
    int numJour = d.getDay();

  int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
  Long DateLundi,DateMardi,DateMercredi,DateJeudi,DateVendredi,DateSamedi;
  Date DateLundiStr,DateMardiStr,DateMercrediStr,DateJeudiStr,DateVendrediStr,DateSamediStr;
  String Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi;
  List<Date> ListJour = new ArrayList<Date>();
  DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 

    switch (numJour) {
      case 1: //MONDAY
      DateMardi = d.getTime() + MILLIS_IN_DAY;
      DateMardiStr = new Date(DateMardi);
      DateMercredi = d.getTime() + 2*MILLIS_IN_DAY;
      DateMercrediStr = new Date(DateMercredi);
      DateJeudi = d.getTime() + 3*MILLIS_IN_DAY;
      DateJeudiStr = new Date(DateJeudi);
      DateVendredi = d.getTime() + 4*MILLIS_IN_DAY;
      DateVendrediStr = new Date(DateVendredi);
      DateSamedi = d.getTime() + 5*MILLIS_IN_DAY;
      DateSamediStr = new Date(DateSamedi);
      Mardi = dateFormat.format(DateMardiStr);
      Mercredi = dateFormat.format(DateMercrediStr);
      Jeudi = dateFormat.format(DateJeudiStr);
      Vendredi = dateFormat.format(DateVendrediStr);
      Samedi = dateFormat.format(DateSamediStr);
      ListJour.add(Mardi);
      ListJour.add(Mercredi);
      ListJour.add(Jeudi);
      ListJour.add(Vendredi);
      ListJour.add(Samedi);
 

        break;
      case 2: //TUESDAY
      DateLundi = d.getTime() - MILLIS_IN_DAY;
      DateLundiStr = new Date(DateLundi);
      DateMercredi = d.getTime() + MILLIS_IN_DAY;
      DateMercrediStr = new Date(DateMercredi);
      DateJeudi = d.getTime() + 2*MILLIS_IN_DAY;
      DateJeudiStr = new Date(DateJeudi);
      DateVendredi = d.getTime() + 3*MILLIS_IN_DAY;
      DateVendrediStr = new Date(DateVendredi);
      DateSamedi = d.getTime() + 4*MILLIS_IN_DAY;
      DateSamediStr = new Date(DateSamedi);
      Lundi = dateFormat.format(DateLundiStr);
      Mercredi = dateFormat.format(DateMercrediStr);
      Jeudi = dateFormat.format(DateJeudiStr);
      Vendredi = dateFormat.format(DateVendrediStr);
      Samedi = dateFormat.format(DateSamediStr);
      ListJour.add(Lundi);
      ListJour.add(Mercredi);
      ListJour.add(Jeudi);
      ListJour.add(Vendredi);
      ListJour.add(Samedi);

        break;
      case 3: //WENDMERCREDI
      DateLundi = d.getTime() - 2*MILLIS_IN_DAY;
      DateLundiStr = new Date(DateLundi);
      DateMardi = d.getTime() - MILLIS_IN_DAY;
      DateMardiStr = new Date(DateMardi);
      DateJeudi = d.getTime() + MILLIS_IN_DAY;
      DateJeudiStr = new Date(DateJeudi);
      DateVendredi = d.getTime() + 2*MILLIS_IN_DAY;
      DateVendrediStr = new Date(DateVendredi);
      DateSamedi = d.getTime() + 3*MILLIS_IN_DAY;
      DateSamediStr = new Date(DateSamedi);
      Lundi = dateFormat.format(DateLundiStr);
      Mardi = dateFormat.format(DateMardiStr);
      Jeudi = dateFormat.format(DateJeudiStr);
      Vendredi = dateFormat.format(DateVendrediStr);
      Samedi = dateFormat.format(DateSamediStr);
      ListJour.add(DateLundiStr);
      ListJour.add(DateMardiStr);
      ListJour.add(DateJeudiStr);
      ListJour.add(DateVendrediStr);
      ListJour.add(DateSamediStr);
      float nombreHeureTotal = 0;
          for (Date Jour : ListJour) {
              Jours J = new Jours(Jour);
          List<Creneau> creneaux = new ArrayList<Creneau>();
    /** @TODO : Appel à la requête du groupe BDD pour le contrôle des créneaux par journée */
    //***************************** Pour les tests *****************************
    /*
    Creneau cr1 = new Creneau();
    cr1.setHorairedebut(700);
    cr1.setHorairefin( 1230);

    Creneau cr2 = new Creneau();
    cr2.setHorairedebut( 1300);
    cr2.setHorairefin(1600);

    creneaux.add(cr1);
    creneaux.add(cr2);*/
    //***************************** Pour les tests *****************************
    /*
    float nombreHeures = 0;
    for (Creneau creneau : creneaux) {
      int heureDebutInt = (int) (creneau.getHorairedebut() / 100);
      System.out.println("heureDebutInt = " + heureDebutInt);

      int heureFinInt = (int) (creneau.getHorairefin() / 100);
      System.out.println("heureFinInt = " + heureFinInt);

      nombreHeures += heureFinInt - heureDebutInt;
      System.out.println("nombreHeures = " + nombreHeures);

      int minuteDebutInt = (int) (creneau.getHorairedebut() % 100);
      System.out.println("minuteDebutInt = " + minuteDebutInt);

      int minuteFinInt = (int) (creneau.getHorairefin() % 100);
      System.out.println("minuteFinInt = " + minuteFinInt);

      nombreHeures += ((float) minuteFinInt - (float) minuteDebutInt) / 60;
      System.out.println("nombreHeures = " + nombreHeures);
      System.out.println("========================================");
    }
    nombreHeureTotal += nombreHeures;
          }
          if (nombreHeureTotal > 36) {
              String date = "" + jour.getIddate();
      message = "La journée du " + date.substring(0, 10) + " compte " + nombreHeureTotal;

      message += " de trop. Une semaine ne doit pas excéder 36 heures.\n";
    }*/
      /*
       System.out.println("Lundi : " + DateLundiStr);
       System.out.println("Mardi : " + DateMardiStr);
       System.out.println("Jeudi : " + DateJeudiStr);
       System.out.println("Vendredi : " + DateVendrediStr);
       System.out.println("Samedi : " + DateSamediStr);
       System.out.println(DateLundiStr.toString());
          
          System.out.println();

          System.out.println(d);*/
/*
        break;
      case 4: //THURSDAY

      DateLundi = d.getTime() - 3*MILLIS_IN_DAY;
      DateLundiStr = new Date(DateLundi);
      DateMardi = d.getTime() - 2*MILLIS_IN_DAY;
      DateMardiStr = new Date(DateMardi);
      DateMercredi = d.getTime() - MILLIS_IN_DAY;
      DateMercrediStr = new Date(DateMercredi);
      DateVendredi = d.getTime() + MILLIS_IN_DAY;
      DateVendrediStr = new Date(DateVendredi);
      DateSamedi = d.getTime() + 2*MILLIS_IN_DAY;
      DateSamediStr = new Date(DateSamedi);
      Mardi = dateFormat.format(DateMardiStr);
      Mercredi = dateFormat.format(DateMercrediStr);
      Lundi = dateFormat.format(DateLundiStr);
      Vendredi = dateFormat.format(DateVendrediStr);
      Samedi = dateFormat.format(DateSamediStr);
      ListJour.add(Mardi);
      ListJour.add(Mercredi);
      ListJour.add(Lundi);
      ListJour.add(Vendredi);
      ListJour.add(Samedi);

        break;
      case 5: //FRIDAY

      DateLundi = d.getTime() - 4*MILLIS_IN_DAY;
      DateLundiStr = new Date(DateLundi);
      DateMardi = d.getTime() - 3*MILLIS_IN_DAY;
      DateMardiStr = new Date(DateMardi);
      DateMercredi = d.getTime() - 2*MILLIS_IN_DAY;
      DateMercrediStr = new Date(DateMercredi);
      DateJeudi = d.getTime() - MILLIS_IN_DAY;
      DateJeudiStr = new Date(DateJeudi);
      DateSamedi = d.getTime() + MILLIS_IN_DAY;
      DateSamediStr = new Date(DateSamedi);
      Mardi = dateFormat.format(DateMardiStr);
      Mercredi = dateFormat.format(DateMercrediStr);
      Jeudi = dateFormat.format(DateJeudiStr);
      Lundi = dateFormat.format(DateLundiStr);
      Samedi = dateFormat.format(DateSamediStr);
      ListJour.add(Mardi);
      ListJour.add(Mercredi);
      ListJour.add(Jeudi);
      ListJour.add(Lundi);
      ListJour.add(Samedi);

        break;
      case 6: //SATURDDAY

      DateLundi = d.getTime() - 5*MILLIS_IN_DAY;
      DateLundiStr = new Date(DateLundi);
      DateMardi = d.getTime() - 4*MILLIS_IN_DAY;
      DateMardiStr = new Date(DateMardi);
      DateMercredi = d.getTime() - 3*MILLIS_IN_DAY;
      DateMercrediStr = new Date(DateMercredi);
      DateJeudi = d.getTime() - 2*MILLIS_IN_DAY;
      DateJeudiStr = new Date(DateJeudi);
      DateVendredi = d.getTime() - MILLIS_IN_DAY;
      DateVendrediStr = new Date(DateVendredi);
      Mardi = dateFormat.format(DateMardiStr);
      Mercredi = dateFormat.format(DateMercrediStr);
      Jeudi = dateFormat.format(DateJeudiStr);
      Vendredi = dateFormat.format(DateVendrediStr);
      Lundi = dateFormat.format(DateLundiStr);
      ListJour.add(Mardi);
      ListJour.add(Mercredi);
      ListJour.add(Jeudi);
      ListJour.add(Vendredi);
      ListJour.add(Lundi);

        break;
    }
    */
    return message;
  }

  private String verifierSalle(Jours jour, Salle salle) {
    String message = "";
    List<Creneau> creneaux = new ArrayList<Creneau>();
    /** @TODO : Appel à la requête du groupe BDD pour le contrôle des créneaux par salle pour une journée */
    //***************************** Pour les tests *****************************
    Creneau cr1 = new Creneau();
    cr1.setHorairedebut(1130);
    cr1.setHorairefin(1200);

    Creneau cr2 = new Creneau();
    cr2.setHorairedebut(1100);
    cr2.setHorairefin(1300);

    creneaux.add(cr2);
    creneaux.add(cr1);
    //***************************** Pour les tests *****************************

    for (int i = 0; i < creneaux.size(); i++) {
      Creneau creneau1 = creneaux.get(i);
      System.out.println(creneau1.getHorairefin());
      for (int j = i + 1; j < creneaux.size(); j++) {
        Creneau creneau2 = creneaux.get(j);

        if ((creneau2.getHorairedebut() > creneau1.getHorairedebut() && creneau2.getHorairedebut() < creneau1.getHorairefin()) ||
            (creneau1.getHorairedebut() > creneau2.getHorairedebut() && creneau1.getHorairedebut() < creneau2.getHorairefin()) ||
            (creneau1.getHorairedebut() > creneau2.getHorairedebut() && creneau1.getHorairefin() < creneau2.getHorairefin()) ||
            (creneau1.getHorairedebut() < creneau2.getHorairedebut() && creneau1.getHorairefin() > creneau2.getHorairefin())) {
          int heuresDebut = Math.min(creneau1.getHorairedebut(), creneau2.getHorairedebut()) / 100;
          int minutesDebut = Math.min(creneau1.getHorairedebut(), creneau2.getHorairedebut()) % 100;

          int heuresFin = Math.max(creneau1.getHorairefin(), creneau2.getHorairefin()) / 100;
          int minutesFin = Math.min(creneau1.getHorairefin(), creneau2.getHorairefin()) % 100;
          String date = "" + jour.getIddate();
          message = "La salle " + salle.getLieu() + " est occupée par deux créneaux entre " + heuresDebut
                  + "h" + minutesDebut + " et " + heuresFin + "h" + minutesFin + " le " + date.substring(0, 10) + ".\n";
        }
      }
    }
    return message;
  }

  private String verifierIntervenant(Jours jour, Enseignant enseignant) {
    String message = "";
    List<Creneau> creneaux = new ArrayList<Creneau>();
    /** @TODO : Appel à la requête du groupe BDD pour le contrôle des créneaux par salle pour une journée */
    //***************************** Pour les tests *****************************
    Creneau cr1 = new Creneau();
    cr1.setHorairedebut(700);
    cr1.setHorairefin(1300);

    Creneau cr2 = new Creneau();
    cr2.setHorairedebut( 1200);
    cr2.setHorairefin(1300);

    creneaux.add(cr2);
    creneaux.add(cr1);
    //***************************** Pour les tests *****************************
    for (int i = 0; i < creneaux.size(); i++) {
      Creneau creneau1 = creneaux.get(i);
      for (int j = i + 1; j < creneaux.size(); j++) {
        Creneau creneau2 = creneaux.get(j);

        if ((creneau2.getHorairedebut() > creneau1.getHorairedebut() && creneau2.getHorairedebut() < creneau1.getHorairefin()) ||
            (creneau1.getHorairedebut() > creneau2.getHorairedebut() && creneau1.getHorairedebut() < creneau2.getHorairefin()) ||
            (creneau1.getHorairedebut() > creneau2.getHorairedebut() && creneau1.getHorairefin() < creneau2.getHorairefin()) ||
            (creneau1.getHorairedebut() < creneau2.getHorairedebut() && creneau1.getHorairefin() > creneau2.getHorairefin())) {
          int heuresDebut = Math.min(creneau1.getHorairedebut(), creneau2.getHorairedebut()) / 100;
          int minutesDebut = Math.min(creneau1.getHorairedebut(), creneau2.getHorairedebut()) % 100;

          int heuresFin = Math.max(creneau1.getHorairefin(), creneau2.getHorairefin()) / 100;
          int minutesFin = Math.min(creneau1.getHorairefin(), creneau2.getHorairefin()) % 100;
          String date = "" + jour.getIddate();
          message = "L'enseignant " + enseignant.getPrenom() + " " + enseignant.getNom() + " est affecté sur deux créneaux entre " + heuresDebut
                  + "h" + minutesDebut + " et " + heuresFin + "h" + minutesFin + " le " + date.substring(0, 10) + ".\n";
        }
      }
    }
    return message;
  }

  private void ecrireMessageErreur(BufferedWriter bw, String message) {
    try {
      bw.append("Attention : " + message);
    }
    catch (FileNotFoundException fnfe) {
      fnfe.printStackTrace();
    }
    catch (UnsupportedEncodingException uee) {
      uee.printStackTrace();
    }
    catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }
}
